home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
mac
/
util
/
multifin
/
monproc2.sit
/
Monitor Process Folder
/
The Source Code
/
moni.c
next >
Wrap
C/C++ Source or Header
|
1991-09-16
|
51KB
|
1,602 lines
/********************************************************************************/
/* */
/* This program will display a list of current processes that exist on the */
/* Macintosh in use (running under System 7) by using the Process Manager which */
/* is new to the Macintosh Toolbox in System 7. */
/* */
/* Programmer: Matthew B. Evans (alias Spaceship) */
/* Date: August 1, 1991 */
/* System: Macintosh II, PMMU, 13MB virtual, one Apple 13" monitor. */
/* Devl System: Symantec's THINK C v5.0 */
/* Notes: This program makes use of several libraries written by */
/* myself. They only aid in shortening code, they do not */
/* affect the theory of the code. */
/* */
/********************************************************************************/
/* */
/* Future Enhancements */
/* ------------------- */
/* */
/* o Put ticks into minutes and seconds. */
/* o Draw icons? */
/* o Add in file location. */
/* o Fix CPU time. */
/* */
/********************************************************************************/
#include <misclib.h> /* Used for InitToolbox() */
#include <dialoglib.h> /* Helps with alerts and dialogs */
#include <ListBox.h> /* My Listbox Manager */
#include <ResHelper.h> /* Shortens code to manipulate resources */
#include <stdio.h> /* ANSI C includes */
/********************************************************************************/
/* Defines and macros */
#define MONITOR_WIND_ID 2000 /* WIND/DITL resource IDs */
#define ABOUT_DLOG_ID 3000 /* DLOG/DITL resource IDs */
#define PREFS_DLOG_ID 3001
#define INFO_DLOG_ID 3002
#define ERROR_ALERT_ID 1000 /* ALRT/DITL resource IDs */
#define BAD_RESOURCES 1001
#define PREF_REFRESH_ITEM 3 /* PREFS_DLOG_ID DITL numbers */
#define PREF_DEF_WINDOW 7
#define PREF_AUTO_UPDATE 8
#define PREF_HIDE_IN_BACK 9
#define PREF_SAVE_PREFS 11
#define INFO_NAME 13 /* INFO_DLOG_ID DITL numbers */
#define INFO_PSN 14
#define INFO_TYPE 15
#define INFO_SIGNATURE 16
#define INFO_ADDRESS 17
#define INFO_SIZE 18
#define INFO_FREEMEM 19
#define INFO_LAUNCHER 20
#define INFO_DATE 21
#define INFO_CPU_TIME 22
#define INFO_LOCATION 23
#define INFO_DA 24
#define INFO_MULTI_LAUNCH 25
#define INFO_SUSPEND_RESUME 26
#define INFO_CAN_BACKGROUND 27
#define INFO_ACTIVATE_FGSWITCH 28
#define INFO_ONLY_BACKGROUND 29
#define INFO_GET_FRONT_CLICKS 30
#define INFO_GET_APP_DIED_EVT 31
#define INFO_32BIT_COMPATIBLE 32
#define INFO_HLEVENT_AWARE 33
#define INFO_LOCAL_REMOTE_HLE 34
#define INFO_STATIONERY_AWARE 35
#define INFO_TEXTEDIT_SERVICES 36
#define INFO_SYSTEM 38
#define ERROR_STRINGS_ID 1000 /* 'STR#' resources */
#define STR_SYSTEM7_REQUIRED 1 /* ERROR_STRINGS_ID string indexes */
#define STR_CANT_GET_RESOURCES 2
#define STR_OUT_OF_MEMORY 3
#define STR_APP_NO_AE 4
#define STR_APP_NOT_FOUND 5
#define APPLE_MENU_ID 1000 /* MENU resource IDs */
#define FILE_MENU_ID 1001
#define EDIT_MENU_ID 1002
#define OTHER_MENU_ID 1003
#define APPLE_ABOUT 1 /* Apple menu items */
#define FILE_NEW_MONITOR 1 /* File menu items */
#define FILE_CLOSE_WINDOW 2
#define FILE_LAUNCH 4
#define FILE_QUIT 6
#define EDIT_UNDO 1 /* Edit menu items */
#define EDIT_CUT 3
#define EDIT_COPY 4
#define EDIT_PASTE 5
#define EDIT_CLEAR 6
#define EDIT_SELECTALL 8
#define OTHER_PREFERENCES 1 /* Other menu items */
#define OTHER_BRING_TO_FRONT 3
#define OTHER_PROCESS_INFO 4
#define OTHER_UPDATE 5
#define OTHER_QUIT 6
#define MAIN_LIST_BOX 2 /* MAIN_DLOG_ID item IDs */
#define MAIN_TITLE 1
#define LISTBOX_TEXT_FONT monaco /* Font info for monitor window */
#define LISTBOX_TEXT_SIZE 9
#define LISTBOX_TITLE_FONT monaco
#define LISTBOX_TITLE_SIZE 9
#define LISTBOX_TITLE_STYLE bold
#define LISTBOX_SORTED_STYLE bold | underline
#define TICKS_PER_SECOND 60 /* Defined by Macintosh */
#define REFRESH_MONITOR_TICKS (5.0 * TICKS_PER_SECOND) /* Default, 5 seconds */
#define MIN_REFRESH_RATE (0.1 * TICKS_PER_SECOND) /* 1/10th second */
#define MAX_REFRESH_RATE (10.0 * TICKS_PER_SECOND) /* 10 seconds */
#define PREF_RES_TYPE 'PREF' /* PREFerence resources */
#define DEF_WIND_POS_ID 1000 /* Default window position */
#define REFRESH_RATE_ID 1001 /* Refresh rate preference */
#define OPEN_DEF_WIND_ID 1002 /* Open default window on startup? */
#define AUTO_UPDATE_ID 1003 /* Update window automatically? */
#define HIDE_IN_BACKGROUND 1004 /* Hide window in background? */
#define DEF_WIND_VERTICAL 1005 /* Default vertical window size */
#define DEF_SAVE_PREFS 1006 /* Save preference items? */
#define MAX_PROCESSES 100 /* Max processes program can handle */
#define SCROLLBAR_WIDTH 16
/********************************************************************************/
/* Global variables */
Rect gGrowRect, gZoomRect; /* Limits: growing, zooming */
int gInBackground; /* Is application currently running in background? */
int gDone; /* Has user chosen Quit from the menu? */
int gHasGestalt; /* Is Gestalt available? */
long gHasAppleEvents; /* Are Apple Events available? */
long gHasStandardFile; /* Has new standard file manager calls */
MenuHandle gAppleMenu, gFileMenu, gEditMenu, gOtherMenu; /* Menus */
WindowPtr gMonitorWindow; /* The monitor window! */
ListBoxPtr gMonitorLB; /* Listbox for monitor window */
Point gMonitorWindPt; /* Default monitor window position */
int gWindowHeight; /* Window vertical size default */
int gRefreshRate; /* Number of ticks before refresh */
int gOpenDefWindow; /* Open window on startup? */
int gAutoUpdate; /* Update automatically? */
int gHideInBackground; /* Hide window in background? */
int gSavePrefs; /* Restore window size/position? */
ProcessSerialNumber *PSNs; /* List of PSNs */
/********************************************************************************/
/* Prototypes */
void InitProgram(void);
void DoEvents(void);
void Cleanup(void);
void HandleSetupMenus(EventRecord *theEvent);
void HandleMenuCommand(long theCommand);
void HandleInContent(WindowPtr theWindow, EventRecord *theEvent);
void HandleCloseWindow(WindowPtr theWindow);
void HandleUpdateWindow(WindowPtr theWindow);
void HandleActivateWindow(WindowPtr theWindow, int activate);
void HandleSuspendResume(int resume);
void HandleInZoomBox(WindowPtr theWindow, EventRecord *theEvent, int windowPart);
void HandleHighLevelEvent(EventRecord *theEvent);
void HandleNullEvent(void);
void HandleSendAEQuit(ProcessSerialNumber *thePSN);
pascal OSErr HandleAEOpenApp(AppleEvent *theAE, AppleEvent *replyAE, long refCon);
pascal OSErr HandleAEQuit(AppleEvent *theAE, AppleEvent *replyAE, long refCon);
void HandleOpenMonitor(void);
void HandleLaunchApp(void);
void HandleAboutDialog(void);
void HandlePreferencesDialog(void);
void HandleProcessInfoDialog(ProcessSerialNumber *thePSN);
OSErr MyGotRequiredParams(AppleEvent *theAE);
void ResizeMonitorWindow(int height, int width);
void CalcMonitorWindow(void);
void DoAlert(int alertType, int stringID, char *text);
pascal Boolean GenericDialogFilter(DialogPtr theDialog, EventRecord *theEvent,
int *theItem);
/********************************************************************************/
/* */
/* Begin the program. */
/* */
/********************************************************************************/
main()
{
InitToolbox(); /* Standard Macintosh toolbox inits */
gDone = FALSE; /* Do program until gDone == TRUE */
InitProgram();
if (!gDone) /* Was the init good? */
DoEvents(); /* Handle events/do the program */
Cleanup(); /* Clean up variables and memory, etc. */
}
/********************************************************************************/
/* */
/* This routine initializes any variables needed by the program; generally */
/* these are global variables, allocating memory for whatever uses, etc. This */
/* code sets up the program and is needed before an AE of OpenApp occurs. */
/* */
/********************************************************************************/
void InitProgram(void)
{
int i;
for (i=0; i<10; i++) /* Increase the size of the heap a little */
MaxApplZone();
InitResHelper(); /* Initialize my libraries */
InitListBox_LB();
InitMiscLib();
InitDialogLib();
/* We want Gestalt to continue (we're being snotty! Well, this is a */
/* System 7 app! I declare it so!) */
if (!TrapAvailable(_Gestalt))
{
DoAlert(STOP_ALERT, STR_SYSTEM7_REQUIRED, "");
gDone = TRUE;
}
else /* Do we have all the Toolbox Managers/thing-a-ma-bobs before continuing? */
{
if ((Gestalt(gestaltAppleEventsAttr, &gHasAppleEvents) != noErr) ||
(Gestalt(gestaltStandardFileAttr, &gHasStandardFile) != noErr))
{
DoAlert(STOP_ALERT, STR_SYSTEM7_REQUIRED, "");
gDone = TRUE;
}
/* All this is documented in Inside Macintosh VI. */
gHasAppleEvents = BitTst(&gHasAppleEvents, 31-gestaltAppleEventsPresent);
gHasStandardFile = BitTst(&gHasStandardFile, 31-gestaltStandardFile58);
if (!gHasAppleEvents || !gHasStandardFile)
{
DoAlert(STOP_ALERT, STR_SYSTEM7_REQUIRED, "");
gDone = TRUE;
}
}
gAppleMenu = GetMenu(APPLE_MENU_ID); /* Set up the menu bar */
gFileMenu = GetMenu(FILE_MENU_ID);
gEditMenu = GetMenu(EDIT_MENU_ID);
gOtherMenu = GetMenu(OTHER_MENU_ID);
if ((gAppleMenu == NULL) || /* Make sure the menu resources exist */
(gFileMenu == NULL) ||
(gEditMenu == NULL) ||
(gOtherMenu == NULL))
{
DoAlert(STOP_ALERT, STR_CANT_GET_RESOURCES, "");
gDone = TRUE;
}
/* Allocate memory for the PSN array */
PSNs = (ProcessSerialNumber *)malloc(sizeof(ProcessSerialNumber) * MAX_PROCESSES);
if (PSNs == NULL)
{
DoAlert(STOP_ALERT, STR_OUT_OF_MEMORY, "");
gDone = TRUE;
}
if (gDone) /* If we don't have what we need so far, return now */
return;
InsertMenu(gAppleMenu, 0); /* Add menus to the menu bar */
InsertMenu(gFileMenu, 0);
InsertMenu(gEditMenu, 0);
InsertMenu(gOtherMenu, 0);
AddResMenu(gAppleMenu, 'DRVR'); /* Add DAs to Apple menu */
DrawMenuBar();
gInBackground = FALSE; /* We start in the foreground */
if (gHasAppleEvents) /* Support OpenApp & Quit AppleEvents */
{
AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
(EventHandlerProcPtr)HandleAEOpenApp, (long)0, FALSE);
AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
(EventHandlerProcPtr)HandleAEQuit, (long)0, FALSE);
}
/* Read in preferences (resources) */
{
Point defPt = {0, 0};
int zero = 0;
int defRR = REFRESH_MONITOR_TICKS;
int false = FALSE, true = TRUE;
GetRes(PREF_RES_TYPE, DEF_WIND_POS_ID, "Window Position", sizeof(Point),
&gMonitorWindPt, &defPt);
GetRes(PREF_RES_TYPE, REFRESH_RATE_ID, "Refresh Rate", sizeof(int),
&gRefreshRate, &defRR);
GetRes(PREF_RES_TYPE, OPEN_DEF_WIND_ID, "Open Default Window", sizeof(int),
&gOpenDefWindow, &false);
GetRes(PREF_RES_TYPE, AUTO_UPDATE_ID, "Auto Update", sizeof(int),
&gAutoUpdate, &true);
GetRes(PREF_RES_TYPE, HIDE_IN_BACKGROUND, "Hide In Background", sizeof(int),
&gHideInBackground, &false);
GetRes(PREF_RES_TYPE, DEF_WIND_VERTICAL, "Window Height", sizeof(int),
&gWindowHeight, &zero);
GetRes(PREF_RES_TYPE, DEF_SAVE_PREFS, "Save Window Size/Pos", sizeof(int),
&gSavePrefs, &true);
}
gMonitorLB = NULL; /* Initialize our global variables */
gMonitorWindow = NULL;
}
/********************************************************************************/
/* */
/* This routine handles the main event loop and distributes events to other */
/* routines. */
/* */
/********************************************************************************/
void DoEvents(void)
{
EventRecord theEvent;
int windowPart;
WindowPtr whichWindow;
long newSize;
while (!gDone)
{
/* Get NULL event every 60 ticks (1 second) */
WaitNextEvent(everyEvent, &theEvent, 60L, NULL);
switch (theEvent.what) /* Do the event */
{
case mouseUp:
IsDblClick(&theEvent); /* Set things up for double clicks */
break;
case mouseDown:
windowPart = FindWindow(theEvent.where, &whichWindow);
switch (windowPart)
{
case inMenuBar:
HandleSetupMenus(&theEvent);
HandleMenuCommand(MenuSelect(theEvent.where));
break;
case inSysWindow:
SystemClick(&theEvent, whichWindow);
break;
case inContent:
if (whichWindow != FrontWindow())
SelectWindow(whichWindow);
else
HandleInContent(whichWindow, &theEvent);
break;
case inDrag:
DragWindow(whichWindow, theEvent.where, &globalDragRect);
/* Save the window position */
if (whichWindow == gMonitorWindow)
{
GrafPtr oldPort;
GetPort(&oldPort);
SetPort(whichWindow);
SetPt(&gMonitorWindPt, 0, 0);
LocalToGlobal(&gMonitorWindPt);
SetPort(oldPort);
WriteRes(&gMonitorWindPt);
}
break;
case inGrow:
newSize = GrowWindow(whichWindow, theEvent.where, &gGrowRect);
if (newSize != (long)0)
ResizeMonitorWindow(HiWord(newSize), LoWord(newSize));
break;
case inGoAway:
if (TrackGoAway(whichWindow, theEvent.where))
HandleCloseWindow(whichWindow);
break;
case inZoomIn:
HandleInZoomBox(whichWindow, &theEvent, inZoomIn);
break;
case inZoomOut:
HandleInZoomBox(whichWindow, &theEvent, inZoomOut);
}
break;
case keyDown:
HandleSetupMenus(&theEvent);
HandleMenuCommand(MenuKey((char)(theEvent.message & charCodeMask)));
break;
case updateEvt:
HandleUpdateWindow((WindowPtr)theEvent.message);
break;
case activateEvt:
HandleActivateWindow((WindowPtr)theEvent.message,
(int)(theEvent.modifiers & activeFlag));
break;
case osEvt:
/* What particular kind of OS event is this */
switch ((theEvent.message & 0xFF000000) >> 24)
{
case suspendResumeMessage:
HandleSuspendResume((int)(theEvent.message & resumeFlag));
break;
case mouseMovedMessage:
break;
}
break;
case kHighLevelEvent:
HandleHighLevelEvent(&theEvent);
break;
case nullEvent:
HandleNullEvent();
break;
}
}
}
/********************************************************************************/
/* */
/* This routine cleans up memory, frees up used memory, etc. and sets gDone to */
/* TRUE so the program will quit on next event loop. */
/* */
/********************************************************************************/
void Cleanup(void)
{
if (gMonitorWindow != NULL)
{
/* Clean up things associated with the window */
DisposeListBox_LB(gMonitorLB);
DisposeWindow(gMonitorWindow);
gMonitorLB = NULL;
gMonitorWindow = NULL;
}
/* Remove the menus from the menu list */
DeleteMenu(APPLE_MENU_ID);
DeleteMenu(FILE_MENU_ID);
DeleteMenu(EDIT_MENU_ID);
DeleteMenu(OTHER_MENU_ID);
/* Free up the menu memory */
DisposeMenu(gAppleMenu);
DisposeMenu(gFileMenu);
DisposeMenu(gEditMenu);
DisposeMenu(gOtherMenu);
/* Remove Apple Events from the Apple Event Manager dispatch table */
if (gHasAppleEvents)
{
AERemoveEventHandler(kCoreEventClass, kAEOpenApplication,
(EventHandlerProcPtr)HandleAEOpenApp, FALSE);
AERemoveEventHandler(kCoreEventClass, kAEQuitApplication,
(EventHandlerProcPtr)HandleAEQuit, FALSE);
}
free(PSNs); /* Free up this array */
gDone = TRUE;
}
/********************************************************************************/
/* */
/* Use this routine to dim, highlight, checkmark, etc. the menus depending on */
/* the current state of the program. */
/* */
/********************************************************************************/
void HandleSetupMenus(EventRecord *theEvent)
{
/* I know the Edit menu is always dim, but things loog good here. */
DisableItem(gEditMenu, EDIT_UNDO);
DisableItem(gEditMenu, EDIT_CUT);
DisableItem(gEditMenu, EDIT_PASTE);
DisableItem(gEditMenu, EDIT_CLEAR);
DisableItem(gEditMenu, EDIT_SELECTALL);
if (gMonitorWindow == NULL)
{
EnableItem(gFileMenu, FILE_NEW_MONITOR);
DisableItem(gFileMenu, FILE_CLOSE_WINDOW);
DisableItem(gEditMenu, EDIT_COPY);
DisableItem(gOtherMenu, OTHER_BRING_TO_FRONT);
DisableItem(gOtherMenu, OTHER_PROCESS_INFO);
DisableItem(gOtherMenu, OTHER_UPDATE);
DisableItem(gOtherMenu, OTHER_QUIT);
}
else /* The monitor window is open */
{
DisableItem(gFileMenu, FILE_NEW_MONITOR);
EnableItem(gFileMenu, FILE_CLOSE_WINDOW);
EnableItem(gOtherMenu, OTHER_UPDATE);
/* Is anything selected? */
if (GetSelected_LB(gMonitorLB) != LB_NoneSelected)
{
EnableItem(gEditMenu, EDIT_COPY);
EnableItem(gOtherMenu, OTHER_BRING_TO_FRONT);
EnableItem(gOtherMenu, OTHER_PROCESS_INFO);
EnableItem(gOtherMenu, OTHER_QUIT);
}
else
{
DisableItem(gEditMenu, EDIT_COPY);
DisableItem(gOtherMenu, OTHER_BRING_TO_FRONT);
DisableItem(gOtherMenu, OTHER_PROCESS_INFO);
DisableItem(gOtherMenu, OTHER_QUIT);
}
}
}
/********************************************************************************/
/* */
/* Use this routine to parse out which menu item was chosen and then dispatch */
/* the command. */
/* */
/********************************************************************************/
void HandleMenuCommand(long theCommand)
{
int menuID, menuItem, accNumber;
Str255 accName;
GrafPtr oldPort;
char tempStr[256];
menuID = HiWord(theCommand);
menuItem = LoWord(theCommand);
switch (menuID)
{
case APPLE_MENU_ID:
switch (menuItem)
{
case APPLE_ABOUT:
HandleAboutDialog();
break;
default: /* DAs */
GetItem(gAppleMenu, menuItem, accName);
accNumber = OpenDeskAcc(accName);
break;
}
break;
case EDIT_MENU_ID:
switch (menuItem)
{
/* Support Copy by getting the text of the selected item */
case EDIT_COPY:
strcpy(tempStr, GetRowText_LB(gMonitorLB, GetSelected_LB(gMonitorLB)));
ZeroScrap();
PutScrap((long)strlen(tempStr), 'TEXT', tempStr);
break;
}
break;
case FILE_MENU_ID:
switch (menuItem)
{
case FILE_NEW_MONITOR:
HandleOpenMonitor();
break;
case FILE_CLOSE_WINDOW:
HandleCloseWindow(FrontWindow());
break;
case FILE_LAUNCH:
HandleLaunchApp();
break;
case FILE_QUIT:
Cleanup();
break;
}
break;
case OTHER_MENU_ID:
switch (menuItem)
{
case OTHER_PREFERENCES:
HandlePreferencesDialog();
break;
case OTHER_BRING_TO_FRONT:
SetFrontProcess(&PSNs[GetSelected_LB(gMonitorLB)]);
break;
case OTHER_PROCESS_INFO:
HandleProcessInfoDialog(&PSNs[GetSelected_LB(gMonitorLB)]);
break;
case OTHER_UPDATE:
CalcMonitorWindow();
DrawListBox_LB(gMonitorLB);
break;
case OTHER_QUIT:
HandleSendAEQuit(&PSNs[GetSelected_LB(gMonitorLB)]);
break;
}
break;
}
HiliteMenu(0); /* Turn off the menu highlighting the Mac did */
}
/********************************************************************************/
/* */
/* When a click occurs inside a window, this routine gets called. You will */
/* need to see what item got clicked on! */
/* */
/********************************************************************************/
void HandleInContent(WindowPtr theWindow, EventRecord *theEvent)
{
ListBoxPtr whichListBox;
/* Is is our window? Was the click in the listbox? Was it a double-click? */
if ((theWindow == gMonitorWindow) &&
(PtInListBox_LB(gMonitorWindow, theEvent->where, &whichListBox)))
if (TrackListBox_LB(whichListBox, theEvent->where, theEvent->modifiers) &&
(IsDblClick(theEvent)))
SetFrontProcess(&PSNs[GetSelected_LB(gMonitorLB)]);
#ifdef TEST
if (IsDblClick(theEvent))
SetFrontProcess(&PSNs[GetSelected_LB(gMonitorLB)]);
else /* Track the mouse in the listbox */
TrackListBox_LB(whichListBox, theEvent->where, theEvent->modifiers);
#endif
}
/********************************************************************************/
/* */
/* Use this routine to handle things when a window is closed (either by the */
/* menu or by the close box). The window being closed is theWindow. */
/* */
/********************************************************************************/
void HandleCloseWindow(WindowPtr theWindow)
{
if (theWindow == gMonitorWindow)
{
DisposeListBox_LB(gMonitorLB);
gMonitorLB = NULL;
DisposeWindow(gMonitorWindow);
gMonitorWindow = NULL;
}
}
/********************************************************************************/
/* */
/* Do your window updating in this routine. The window that needs to be */
/* updated is theWindow. */
/* */
/********************************************************************************/
void HandleUpdateWindow(WindowPtr theWindow)
{
GrafPtr oldPort;
GetPort(&oldPort);
SetPort(theWindow);
BeginUpdate(theWindow);
/* Draw contents for theWindow here */
if (theWindow == gMonitorWindow)
{
DrawListBox_LB(gMonitorLB);
DrawGrowBoxOnly(gMonitorWindow);
}
EndUpdate(theWindow);
SetPort(oldPort);
}
/********************************************************************************/
/* */
/* Hilite/dehilight the window here. */
/* */
/********************************************************************************/
void HandleActivateWindow(WindowPtr theWindow, int activate)
{
if (theWindow == NULL)
return;
if (activate) /* Is theWindow coming to the foreground? */
{
if (theWindow == gMonitorWindow)
ListBoxState_LB(gMonitorLB, LB_Activate);
InitCursor(); /* Just in case another app sets it to something else */
}
else /* We're deactivating theWindow */
{
if (theWindow == gMonitorWindow)
ListBoxState_LB(gMonitorLB, LB_Deactivate);
}
}
/********************************************************************************/
/* */
/* Handle suspend and resume events here. We need to handle activate events */
/* ourself if we are being suspended or resuming. */
/* */
/********************************************************************************/
void HandleSuspendResume(int resume)
{
if (resume) /* Is our app coming to the foreground? */
{
if (gMonitorWindow != NULL)
if (gHideInBackground)
ShowWindow(gMonitorWindow);
else
HandleActivateWindow(gMonitorWindow, TRUE);
gInBackground = FALSE;
}
else /* We are being suspended, our app is going to the background */
{
if (gMonitorWindow != NULL)
if (gHideInBackground)
HideWindow(gMonitorWindow);
else
HandleActivateWindow(gMonitorWindow, FALSE);
gInBackground = TRUE;
}
}
/********************************************************************************/
/* */
/* This routine will handle things when the user clicks on the zoom box. */
/* */
/********************************************************************************/
void HandleInZoomBox(WindowPtr theWindow, EventRecord *theEvent, int windowPart)
{
long centerLat, centerLong;
GrafPtr oldPort;
Rect sbRect;
FontInfo auxWindFont;
GetPort(&oldPort);
SetPort(theWindow);
if (TrackBox(theWindow, theEvent->where, windowPart))
{
EraseRect(&theWindow->portRect); /* ZoomWindow() says to do this */
ZoomWindow(theWindow, windowPart, FALSE); /* Zoom in or out (depending on windowpart) */
}
SetPort(oldPort);
}
/********************************************************************************/
/* */
/* This routine calls to the Apple Event Manager to handle Apple Events. */
/* */
/********************************************************************************/
void HandleHighLevelEvent(EventRecord *theEvent)
{
OSErr err;
err = AEProcessAppleEvent(theEvent); /* Dispatch the Apple Event */
}
/********************************************************************************/
/* */
/* Do background tasks here. Remember to set the 'SIZE' resource bits properly */
/* so you will get NULL events if you want them! */
/* */
/********************************************************************************/
void HandleNullEvent(void)
{
static long currTicks = 0;
long newTicks;
if (currTicks == 0) /* This will only happen on first NULL event */
currTicks = TickCount();
/* Here we check to see if a period of time has gone by, if so, update */
/* the window if it is open. */
if (gMonitorLB != NULL)
{
newTicks = currTicks + (long)gRefreshRate;
if (newTicks < TickCount())
{
if (gAutoUpdate) /* Is pref set to update automatically? */
{
CalcMonitorWindow();
DrawListBox_LB(gMonitorLB);
}
currTicks = TickCount();
}
}
}
/********************************************************************************/
/* */
/* This routine handles the "Open Application" Apple Event. */
/* */
/********************************************************************************/
pascal OSErr HandleAEOpenApp(AppleEvent *theAE, AppleEvent *replyAE, long refCon)
{
OSErr err;
err = MyGotRequiredParams(theAE); /* All parameters gotten? */
if (err == noErr) /* If no errors, perform program "opening" */
{
if (gOpenDefWindow) /* Do we need to start with an open window? */
HandleOpenMonitor();
}
return(err);
}
/********************************************************************************/
/* */
/* This routine handles the "Quit Application" Apple Event. */
/* */
/********************************************************************************/
pascal OSErr HandleAEQuit(AppleEvent *theAE, AppleEvent *replyAE, long refCon)
{
OSErr err;
err = MyGotRequiredParams(theAE); /* All parameters gotten? */
if (err == noErr) /* If no errors, quit program */
Cleanup(); /* Clean up variables and memory, etc. */
return(err);
}
/********************************************************************************/
/* */
/* This routine will send a high level Apple Event to the specified application */
/* ONLY if the application is high level event aware. */
/* */
/* Input: thePSN = The process serial number of the app to send the AE to. */
/* */
/* Note: This is my first attempt at Apple Events, so the code probably */
/* doesn't look too good. */
/* */
/********************************************************************************/
void HandleSendAEQuit(ProcessSerialNumber *thePSN)
{
ProcessInfoRec theProcInfo;
Str255 procName, otherName;
FSSpec locationName;
char tempStr[256];
OSErr err;
AEAddressDesc targetAddress;
AppleEvent theAE, replyAE;
Handle psnHandle;
/* Prepare and then get the process information */
theProcInfo.processInfoLength = sizeof(ProcessInfoRec);
theProcInfo.processName = procName;
theProcInfo.processAppSpec = &locationName;
err = GetProcessInformation(thePSN, &theProcInfo);
if (err == noErr)
{
if (theProcInfo.processMode & modeHighLevelEventAware)
{
/* Set up the targetAddress (thePSN info for the Apple Event Manger) */
psnHandle = NewHandle((Size)sizeof(ProcessSerialNumber));
*((ProcessSerialNumber *)*psnHandle) = *thePSN;
targetAddress.descriptorType = typeProcessSerialNumber; /* We are using PSN */
targetAddress.dataHandle = psnHandle;
/* Create the Apple Event "Quit" */
err = AECreateAppleEvent('aevt',
'quit',
&targetAddress,
kAutoGenerateReturnID,
kAnyTransactionID,
&theAE);
/* Send the Apple Event */
AESend(&theAE,
&replyAE,
kAENoReply + kAENeverInteract + kAECanSwitchLayer,
kAENormalPriority,
kAEDefaultTimeout,
NULL,
NULL);
}
else
DoAlert(NOTE_ALERT, STR_APP_NO_AE, ""); /* App not AE aware */
}
else
DoAlert(NOTE_ALERT, STR_APP_NOT_FOUND, ""); /* App not found anymore */
}
/********************************************************************************/
/* */
/* This routine will open up and create structures for the monitor process */
/* window. */
/* */
/********************************************************************************/
void HandleOpenMonitor(void)
{
Rect tempRect;
int titleWidth;
gMonitorWindow = GetNewWindow(MONITOR_WIND_ID, NULL, (WindowPtr)-1);
if (gMonitorWindow == NULL)
{
DisplayAlert(BAD_RESOURCES, STOP_ALERT, NULL);
return;
}
/* Set the window size to that of the prefs if the user wants to */
if (gSavePrefs && (gWindowHeight != 0))
SizeWindow(gMonitorWindow,
gMonitorWindow->portRect.right - gMonitorWindow->portRect.left,
gWindowHeight,
FALSE);
/* Create the listbox rect */
SetRect(&tempRect,
gMonitorWindow->portRect.left - 1,
gMonitorWindow->portRect.top - 1,
gMonitorWindow->portRect.right + 1,
gMonitorWindow->portRect.bottom + 1);
/* Create the list box */
gMonitorLB = NewListBox_LB(gMonitorWindow, &tempRect, FALSE, NULL, NULL);
ListBoxState_LB(gMonitorLB, LB_GrowBoxOn);
TextFont_LB(gMonitorLB, LISTBOX_TEXT_FONT);
TextSize_LB(gMonitorLB, LISTBOX_TEXT_SIZE);
/* Set up the title for the listbox */
TitleFont_LB(gMonitorLB, LISTBOX_TITLE_FONT);
TitleSize_LB(gMonitorLB, LISTBOX_TITLE_SIZE);
TitleStyle_LB(gMonitorLB, LISTBOX_TITLE_STYLE, LISTBOX_SORTED_STYLE);
/* Note: This title must match the data inserted into the listbox for field widths! */
SetTitleText_LB(gMonitorLB, "Process Name ]Type ]Sign ]Location ]Size ]Free ", 0L);
ListBoxState_LB(gMonitorLB, LB_TitleOn);
/* Here, we resize the listbox to the width of the listbox title. Then we */
/* size the window to the size of the listbox. This frees us from having to */
/* have the resources exactly match the items we need. The user is free to */
/* modify the WIND resource vertically, but we will override any horizontal */
/* changes. We need this code here instead of calling ResizeMonitorWindow() */
/* so we can initially set up the listbox size. */
GetFieldInfo_LB(gMonitorLB, 0, &titleWidth, NULL, NULL, NULL);
GetRect_LB(gMonitorLB, &tempRect);
tempRect.right = tempRect.left +
titleWidth +
SCROLLBAR_WIDTH +
GetLeftMargin_LB(gMonitorLB)+1; /* +1 for good looks */
ResizeListBox_LB(gMonitorLB, &tempRect);
SizeWindow(gMonitorWindow,
tempRect.right - tempRect.left - 2, /* -2 for borders */
tempRect.bottom - tempRect.top - 2,
FALSE);
/* Since we know the size of the window, let's set the zoomRect and growRect */
gZoomRect = gMonitorWindow->portRect;
/* OffsetRect(&gZoomRect, - */
SetRect(&gZoomRect,
tempRect.right - tempRect.left - 2,
50,
tempRect.right - tempRect.left - 2,
350);
(*((WStateData **)(((WindowPeek)gMonitorWindow)->dataHandle)))->stdState = gZoomRect;
SetRect(&gGrowRect,
tempRect.right - tempRect.left - 1,
80,
tempRect.right - tempRect.left - 1,
screenBits.bounds.bottom - screenBits.bounds.top);
/* Since a new list box has drawing off, let's turn drawing on */
CalcMonitorWindow();
/* Move the window to the default position or center it if the default position doesn't */
/* exist or the default position would otherwise take the window off screen. */
if (!gSavePrefs ||
((gMonitorWindPt.h == 0) &&
(gMonitorWindPt.v == 0) ||
(gMonitorWindPt.h < 5) ||
(gMonitorWindPt.h > (screenBits.bounds.right - 5)) ||
(gMonitorWindPt.v < (MBarHeight + 25)) ||
(gMonitorWindPt.v > (screenBits.bounds.bottom - 5))))
CenterDialog(gMonitorWindow);
else
MoveWindow(gMonitorWindow, gMonitorWindPt.h, gMonitorWindPt.v, TRUE);
ListBoxState_LB(gMonitorLB, LB_DrawOn);
ShowWindow(gMonitorWindow);
}
/********************************************************************************/
/* */
/* This routine will allow the user to launch other applications from this */
/* program. */
/* */
/********************************************************************************/
void HandleLaunchApp(void)
{
LaunchParamBlockRec launchParms;
StandardFileReply theFileReply;
SFTypeList typeList;
typeList[0] = 'APPL'; /* Launch only applications */
typeList[1] = 'FNDR'; /* and the Finder (maybe the user quit it!) */
StandardGetFile(NULL, 2, &typeList, &theFileReply);
if (theFileReply.sfGood)
{
launchParms.launchBlockID = extendedBlock;
launchParms.launchEPBLength = extendedBlockLen;
launchParms.launchFileFlags = 0;
launchParms.launchControlFlags = launchContinue + launchNoFileFlags;
launchParms.launchAppSpec = &theFileReply.sfFile;
launchParms.launchAppParameters = NULL;
LaunchApplication(&launchParms);
}
}
/********************************************************************************/
/* */
/* This routine will display the "About..." dialog. */
/* */
/********************************************************************************/
void HandleAboutDialog(void)
{
DialogPtr theDialog;
int itemHit;
theDialog = GetNewDialog(ABOUT_DLOG_ID, NULL, (WindowPtr)-1);
if (theDialog == NULL)
{
DisplayAlert(BAD_RESOURCES, STOP_ALERT, NULL);
return;
}
CenterDialog(theDialog);
ShowWindow(theDialog);
do
{
ModalDialog(&GenericDialogFilter, &itemHit);
}
while (itemHit != OK);
DisposeDialog(theDialog);
}
/********************************************************************************/
/* */
/* This routine will display and handle the "Preferences..." menu selection/ */
/* dialog. */
/* */
/********************************************************************************/
void HandlePreferencesDialog(void)
{
DialogPtr theDialog;
int itemHit, tempInt;
float tempFloat;
char tempStr[256];
theDialog = GetNewDialog(PREFS_DLOG_ID, NULL, (WindowPtr)-1);
if (theDialog == NULL)
{
DisplayAlert(BAD_RESOURCES, STOP_ALERT, NULL);
return;
}
/* Fill in the current refresh value */
tempFloat = (float)gRefreshRate;
tempFloat /= TICKS_PER_SECOND;
sprintf(tempStr, "%3.1f", tempFloat);
SetItemText(theDialog, PREF_REFRESH_ITEM, tempStr); /* From "dialoglib" */
SelIText(theDialog, PREF_REFRESH_ITEM, 0, 32767); /* Select the entire item */
/* Set the default window checkbox */
SetCheckBox(theDialog, PREF_DEF_WINDOW, gOpenDefWindow);
SetCheckBox(theDialog, PREF_AUTO_UPDATE, gAutoUpdate);
SetCheckBox(theDialog, PREF_HIDE_IN_BACK, gHideInBackground);
SetCheckBox(theDialog, PREF_SAVE_PREFS, gSavePrefs);
CenterDialog(theDialog);
ShowWindow(theDialog);
do
{
ModalDialog(&GenericDialogFilter, &itemHit);
switch (itemHit)
{
case PREF_DEF_WINDOW:
case PREF_AUTO_UPDATE:
case PREF_HIDE_IN_BACK:
case PREF_SAVE_PREFS:
ToggleCheckBox(theDialog, itemHit, &tempInt);
break;
}
}
while ((itemHit != OK) && (itemHit != Cancel));
if (itemHit == OK)
{
/* GetItemTextLen() is from "dialoglib". Get the text the user entered. */
/* If it is valid, use it, otherwise keep the old. */
/* Get the refresh time and verify it is valid */
GetItemTextLen(theDialog, PREF_REFRESH_ITEM, tempStr, 3); /* Only 3 decimal places */
sscanf(tempStr, "%f", &tempFloat);
tempFloat *= TICKS_PER_SECOND;
if ((tempFloat >= MIN_REFRESH_RATE) &&
(tempFloat <= MAX_REFRESH_RATE))
{
gRefreshRate = tempFloat;
WriteRes(&gRefreshRate);
}
/* Save the preferences */
gOpenDefWindow = GetCheckBox(theDialog, PREF_DEF_WINDOW);
WriteRes(&gOpenDefWindow);
gAutoUpdate = GetCheckBox(theDialog, PREF_AUTO_UPDATE);
WriteRes(&gAutoUpdate);
gHideInBackground = GetCheckBox(theDialog, PREF_HIDE_IN_BACK);
WriteRes(&gHideInBackground);
gSavePrefs = GetCheckBox(theDialog, PREF_SAVE_PREFS);
WriteRes(&gSavePrefs);
}
DisposeDialog(theDialog);
}
/********************************************************************************/
/* */
/* This routine will display a dialog of information about the process with the */
/* process serial number thePSN. It has to break down and digest the process */
/* information record. */
/* */
/* Input: thePSN = The process serial number of the process to display info */
/* for. */
/* */
/* Output: None. */
/* */
/********************************************************************************/
void HandleProcessInfoDialog(ProcessSerialNumber *thePSN)
{
DialogPtr theDialog;
int itemHit;
Str255 procName, otherName;
ProcessInfoRec theProcInfo, otherProcInfo;
char tempStr[256];
FSSpec locationName;
theDialog = GetNewDialog(INFO_DLOG_ID, NULL, (WindowPtr)-1);
if (theDialog == NULL)
{
DoAlert(STOP_ALERT, BAD_RESOURCES, "");
return;
}
/* Get the process information and fill in the dialog items */
SetWatchCursor();
/* Prepare and then get the process information */
theProcInfo.processInfoLength = sizeof(ProcessInfoRec);
theProcInfo.processName = procName;
theProcInfo.processAppSpec = &locationName;
if (GetProcessInformation(thePSN, &theProcInfo) != noErr)
{
InitCursor();
DoAlert(NOTE_ALERT, STR_APP_NOT_FOUND, "");
return;
}
/* Fill in the main/easy items in the dialog with info from the process record */
strcpy(tempStr, PtoCstr((char *)theProcInfo.processName));
SetItemText(theDialog, INFO_NAME, tempStr);
sprintf(tempStr, "%08ld/%08ld", theProcInfo.processNumber.highLongOfPSN,
theProcInfo.processNumber.lowLongOfPSN);
SetItemText(theDialog, INFO_PSN, tempStr);
sprintf(tempStr, "'%4.4s'", (char *)&theProcInfo.processType);
SetItemText(theDialog, INFO_TYPE, tempStr);
sprintf(tempStr, "'%4.4s'", (char *)&theProcInfo.processSignature);
SetItemText(theDialog, INFO_SIGNATURE, tempStr);
sprintf(tempStr, "$%lX", theProcInfo.processLocation);
SetItemText(theDialog, INFO_ADDRESS, tempStr);
sprintf(tempStr, "%ld bytes (%ldK)", theProcInfo.processSize, (theProcInfo.processSize / 1024));
SetItemText(theDialog, INFO_SIZE, tempStr);
sprintf(tempStr, "%ld bytes (%ldK)", theProcInfo.processFreeMem, (theProcInfo.processFreeMem / 1024));
SetItemText(theDialog, INFO_FREEMEM, tempStr);
sprintf(tempStr, "%lu ticks", theProcInfo.processLaunchDate);
SetItemText(theDialog, INFO_DATE, tempStr);
sprintf(tempStr, "%lu ticks", theProcInfo.processActiveTime);
SetItemText(theDialog, INFO_CPU_TIME, tempStr);
/* Get the name of the launching/parent process */
otherProcInfo.processInfoLength = sizeof(ProcessInfoRec);
otherProcInfo.processName = otherName;
otherProcInfo.processAppSpec = NULL;
if (GetProcessInformation(&theProcInfo.processLauncher, &otherProcInfo) == noErr)
{
strcpy(tempStr, PtoCstr((char *)otherProcInfo.processName));
SetItemText(theDialog, INFO_LAUNCHER, tempStr);
}
else
SetItemText(theDialog, INFO_LAUNCHER, "Unknown");
/* Get the file location */
/* This item is not shown in the dialog, the staticText item is out of visRgn. */
SetItemText(theDialog, INFO_LOCATION, PtoCstr(theProcInfo.processAppSpec->name));
/* Set the bit fields from the 'SIZE' resource (theProcInfo.Mode field) */
SetCheckBox(theDialog, INFO_DA, (theProcInfo.processMode & modeDeskAccessory));
SetCheckBox(theDialog, INFO_MULTI_LAUNCH, (theProcInfo.processMode & modeMultiLaunch));
SetCheckBox(theDialog, INFO_SUSPEND_RESUME, (theProcInfo.processMode & modeNeedSuspendResume));
SetCheckBox(theDialog, INFO_CAN_BACKGROUND, (theProcInfo.processMode & modeCanBackground));
SetCheckBox(theDialog, INFO_ACTIVATE_FGSWITCH, (theProcInfo.processMode & modeDoesActivateOnFGSwitch));
SetCheckBox(theDialog, INFO_ONLY_BACKGROUND, (theProcInfo.processMode & modeOnlyBackground));
SetCheckBox(theDialog, INFO_GET_FRONT_CLICKS, (theProcInfo.processMode & modeGetFrontClicks));
SetCheckBox(theDialog, INFO_GET_APP_DIED_EVT, (theProcInfo.processMode & modeGetAppDiedMsg));
SetCheckBox(theDialog, INFO_32BIT_COMPATIBLE, (theProcInfo.processMode & mode32BitCompatible));
SetCheckBox(theDialog, INFO_HLEVENT_AWARE, (theProcInfo.processMode & modeHighLevelEventAware));
SetCheckBox(theDialog, INFO_LOCAL_REMOTE_HLE, (theProcInfo.processMode & modeLocalAndRemoteHLEvents));
SetCheckBox(theDialog, INFO_STATIONERY_AWARE, (theProcInfo.processMode & modeStationeryAware));
SetCheckBox(theDialog, INFO_TEXTEDIT_SERVICES, (theProcInfo.processMode & modeUseTextEditServices));
/* And get the system to display the current System Software */
if ((globalSystemVers & 0x000F) == 0) /* Test bug fix version */
{
sprintf(tempStr, "%d.%0d",
((globalSystemVers & 0x0000FF00) >> 8),
((globalSystemVers & 0x000000F0) >> 4));
}
else /* A third (bug) version number must exist, let's add it in */
{
sprintf(tempStr, "%d.%0d.%d",
((globalSystemVers & 0x0000FF00) >> 8),
((globalSystemVers & 0x000000F0) >> 4),
(globalSystemVers & 0x0000000F));
}
SetItemText(theDialog, INFO_SYSTEM, tempStr);
/* And let's clean things up and display the dialog */
InitCursor();
CenterDialog(theDialog);
ShowWindow(theDialog);
/* Handle dialog events */
do
{
ModalDialog(&GenericDialogFilter, &itemHit);
}
while (itemHit != OK);
/* And clean up! */
DisposeDialog(theDialog);
}
/********************************************************************************/
/* */
/* This routine checks to make sure things are OK for getting the correct */
/* number of parameters in the Apple Event. */
/* */
/********************************************************************************/
OSErr MyGotRequiredParams(AppleEvent *theAE)
{
DescType returnedType;
Size actualSize;
OSErr err;
/* Check for next parameter in the Apple Event */
err = AEGetAttributePtr(theAE, keyMissedKeywordAttr, typeWildCard, &returnedType,
NULL, 0L, &actualSize);
if (err == errAEDescNotFound) /* Are there no more parameters? */
err = noErr;
return(err);
}
/********************************************************************************/
/* */
/* This routine calculates the size of the window based on the size of the list */
/* box. */
/* */
/* Input: height = Height of window. */
/* width = Width of window. */
/* */
/********************************************************************************/
void ResizeMonitorWindow(int height, int width)
{
GrafPtr oldPort;
Rect theLBrect;
/* Let's turn off drawing for the listbox so it doesn't */
/* draw while we are resizing the window. We need to */
/* resize the listbox to the size of the new window, but */
/* then we need to size the window to that of the listbox */
/* because the listbox is constrained due to the font. */
/* Use -1 so listbox borders are outside, use +2 to count */
/* the borders that are outside. */
ListBoxState_LB(gMonitorLB, LB_DrawOff);
theLBrect = gMonitorWindow->portRect;
SetRect(&theLBrect,
0,
0,
-1 + width + 2,
-1 + height + 2);
InsetRect(&theLBrect, -1, -1);
ResizeListBox_LB(gMonitorLB, &theLBrect);
GetRect_LB(gMonitorLB, &theLBrect);
/* We use "-2" since the listbox borders are outside */
/* the window and we are using the size of the listbox. */
SizeWindow(gMonitorWindow,
theLBrect.right - theLBrect.left - 2,
theLBrect.bottom - theLBrect.top - 2,
TRUE);
/* Let's force an update event on ourself. */
GetPort(&oldPort);
SetPort(gMonitorWindow);
InvalRect(&gMonitorWindow->portRect);
SetPort(oldPort);
/* Save window size if used in preferences */
gWindowHeight = gMonitorWindow->portRect.bottom - gMonitorWindow->portRect.top;
WriteRes(&gWindowHeight);
ListBoxState_LB(gMonitorLB, LB_DrawOn);
}
/********************************************************************************/
/* */
/* This routine calculates the values and fills in the list box for the */
/* monitor processes listbox (gMonitorLB). This routine does not draw the */
/* window or listbox. */
/* */
/********************************************************************************/
void CalcMonitorWindow(void)
{
ProcessInfoRec theProcInfo;
ProcessSerialNumber thePSN, selectedPSN;
Str255 procName;
char tempStr[256];
int i;
if (gMonitorLB == NULL)
return;
/* Let's remember the selected process. If it still exists after we */
/* rebuild the listbox, let's set it to be the selected process again. */
if (GetSelected_LB(gMonitorLB) != LB_NoneSelected)
selectedPSN = PSNs[GetSelected_LB(gMonitorLB)];
else
{
selectedPSN.lowLongOfPSN = kNoProcess;
selectedPSN.highLongOfPSN = kNoProcess;
}
ListBoxState_LB(gMonitorLB, LB_DrawOff);
EmptyListBox_LB(gMonitorLB);
thePSN.lowLongOfPSN = kNoProcess; /* Used to get first process in list */
thePSN.highLongOfPSN = kNoProcess;
i = 1; /* Because the listbox starts at row 1, not 0 */
/* While a process still exists... */
while (GetNextProcess(&thePSN) != procNotFound)
{
/* Fill in parms for GetProcessInformation() */
theProcInfo.processInfoLength = sizeof(ProcessInfoRec);
theProcInfo.processName = procName;
theProcInfo.processAppSpec = NULL;
GetProcessInformation(&thePSN, &theProcInfo);
/* Fill the listbox with this info */
sprintf(tempStr, "%-21.21s %4.4s %4.4s %08p %5ldK %5ldK",
PtoCstr((char *)theProcInfo.processName),
(char *)&theProcInfo.processType,
(char *)&theProcInfo.processSignature,
theProcInfo.processLocation,
(theProcInfo.processSize / 1024),
(theProcInfo.processFreeMem / 1024));
InsertRow_LB(gMonitorLB, LB_Append, tempStr, (long)i);
PSNs[i++] = theProcInfo.processNumber;
if (i >= MAX_PROCESSES) /* Have we exceeded our array of PSNs? */
break;
}
/* Set selected the process that was selected before the rebuild, if */
/* one was selected. We could have used memcpy() to compare the */
/* structures, but I prefer comparing individual fields. For a small */
/* struct, there is really no time wasted, and it's clearer to the */
/* reader what is really going on. */
for (i=1; i<=GetNumRows_LB(gMonitorLB); i++)
if ((PSNs[i].lowLongOfPSN == selectedPSN.lowLongOfPSN) &&
(PSNs[i].highLongOfPSN == selectedPSN.highLongOfPSN))
{
SetSelected_LB(gMonitorLB, i, TRUE);
break; /* We can only have one item selected */
}
ListBoxState_LB(gMonitorLB, LB_DrawOn);
}
/********************************************************************************/
/* */
/* This routine will display an alert of type alertType with 'STR#' resource of */
/* stringID. If stringID == 0, then text is used for the information. */
/* DisplayAlert() is from the "dialoglib" library. */
/* */
/* Input: alertType = STOP_ALERT, CAUTION_ALERT, or NOTE_ALERT. */
/* stringID = 'STR#' resource string number. */
/* text = Optional text to put into alert (if stringID == 0). */
/* */
/********************************************************************************/
void DoAlert(int alertType, int stringID, char *text)
{
Str255 theString;
if (stringID == 0)
{
strcpy((char *)theString, text);
CtoPstr((char *)theString);
}
else
{
GetIndString(theString, ERROR_STRINGS_ID, stringID);
if ((int)theString[0] == 0)
{
strcpy((char *)theString, "Critical error has occurred. "
"Program may be corrupted. "
"Advise program shutdown.");
CtoPstr((char *)theString);
}
}
ParamText(theString, "\p", "\p", "\p");
DisplayAlert(ERROR_ALERT_ID, alertType, NULL); /* dialoglib call */
ParamText("\p", "\p", "\p", "\p");
}
/********************************************************************************/
/* */
/* This is a generic dialog filter. It handles updates and keyDowns looking */
/* for RETURN, ENTER, and ESCAPE keys. */
/* */
/********************************************************************************/
pascal Boolean GenericDialogFilter(DialogPtr theDialog, EventRecord *theEvent,
int *theItem)
{
GrafPtr oldPort;
*theItem = 0; /* Initialize theItem */
switch (theEvent->what)
{
case updateEvt:
if ((WindowPtr)theEvent->message == theDialog)
{
GetPort(&oldPort);
SetPort(theDialog);
BoldButton(theDialog, OK);
DrawDialogLines(theDialog);
SetPort(oldPort);
}
break;
/* Test the RETURN and ENTER keys to see if the user pressed them */
/* and if so, return OK as the item. (if okFlag is TRUE!) */
case keyDown:
/* Check for special keys, try known ASCII characters */
switch ((char)(theEvent->message & charCodeMask))
{
case RETURN_AKEY:
case ENTER_AKEY:
*theItem = OK;
return(TRUE);
break;
case ESC_AKEY:
*theItem = Cancel;
return(TRUE);
break;
}
break;
}
return(FALSE);
}
/********************************************************************************/